<template>
	<transition :name="`ui-message_${enter}`" @after-leave="afterLeave">
		<div v-show="visible" :class="rootClass" :style="rootStyle">
			<slot></slot>
		</div>
	</transition>
</template>

<script setup>
	import { onMounted, ref, computed } from 'vue';

	const props = defineProps({
		duration: {
			type: Number,
			default: 4000
		},
		position: {
			type: String,
			default: 'tc',
			validator: v => ['tl', 'tc', 'tr', 'bl', 'bc', 'br'].includes(v)
		},
		enter: {
			type: String,
			default: 'slide',
			validator: v => ['slide', 'blink'].includes(v)
		},
		size: {
			type: String,
			default: 'md',
			validator: v=> ['sm', 'md', 'lg'].includes(v)
		},
		width: [Number, String],
		offset: Number,
		zIndex: Number,
		keyClose: {
			type: [Boolean, String],
			default: 'Escape'
		}
	});

	const emits = defineEmits(['close', 'remove']);

	const visible = ref(false);
	
	let timeoutSeed = null;
	
	const rootClass = computed(() => {
		return ['ui-message', `is_${props.position}`, `is_${props.size}`];
	})

	const rootStyle = computed(() => {
		const sty = {
			zIndex: props.zIndex
		};
		sty[/^t/.test(props.position) ? 'top' : 'bottom'] = `${props.offset}px`;
		if (props.width) sty.width = /(%|vw|auto)$/.test(props.width) ? props.width : `${props.width}px`;
		return sty;
	})

	onMounted(() => {
		visible.value = true;
		props.keyClose && document.addEventListener('keydown', closeKeyDown);
		props.duration != 0 && (timeoutSeed = setTimeout(() => close(), props.duration));
	})

	function close() {
		document.removeEventListener('keydown', closeKeyDown);
		clearTimeout(timeoutSeed);
		visible.value = false;
		emits('close');
	}

	function afterLeave() {
		emits('remove');
	}

	function closeKeyDown(e) {
		e.code.toLocaleLowerCase() === props.keyClose.toLocaleLowerCase() && close();
	}
	
	defineExpose({
		close
	})
</script>

<style lang="scss" scoped>
	
	body>.ui-message {
		position: fixed;
		z-index: 712;
	}
	
	.ui-message {
		position: absolute;
		transition: all .25s ease-in-out;
		&.is_sm {
			width: min(80%, 280px);
		}
		&.is_md {
			width: min(80%, 360px);
		}
		&.is_lg {
			width: min(80%, 480px);
		}
		&.is_tl, &.is_bl {
			left: 16px;
		}
		&.is_tc, &.is_bc {
			left: 50%;
			transform: translate(-50%, 0);
		}
		&.is_tr, &.is_br {
			right: 16px;
		}
	}

	.ui-message_slide-enter-from,
	.ui-message_slide-leave-to {
		opacity: 0;
		&.is_tl, &.is_bl {
			left: 0;
			transform: translate(-100%, 0);
		}
		&.is_tc, &.is_bc {
			transform: translate(-50%, -16px);
		}
		&.is_tr, &.is_br {
			right: 0;
			transform: translate(100%, 0);
		}
	}

	.ui-message_blink-enter-from,
	.ui-message_blink-leave-to {
		opacity: 0;
		&.is_tl, &.is_bl {
			transform: scale(.5);
		}
		&.is_tc, &.is_bc {
			transform: translate(-50%, 0)scale(.5);
		}
		&.is_tr, &.is_br {
			transform: scale(.5);
		}
	}
	
</style>
